home *** CD-ROM | disk | FTP | other *** search
- /* >>>>> start ccl <<<<<< */
- /* */
- /* Compiler begins execution here */
- /* */
- #ifndef TRUE /*see if need to use include file */
- #include <c.def>
- #endif
- main()
- {
- glbptr=startglb; /* clear global symbols */
- locptr=startloc; /* clear local symbols */
- wqptr=wq; /* clear while queue */
- macptr= /* clear the macro pool */
- litptr= /* clear literal pool */
- nxtlab= /* next label to assign */
- sp = /* stackptr (relative) */
- errcnt= /* no errors */
- eof= /* not eof yet */
- input= /* no input file */
- input2= /* or include file */
- output= /* no open units */
- ncmp= /* no open compound states */
- ctext= /* do not print text */
- lastst=0; /* no last statement yet */
- cif= /* state of #ifxxxx */
- cmode=1; /* enable preprocessing */
- litlab=getlabel(); /* label number for literal poll */
- /* */
- /* compiler body */
- /* */
- ask(); /* get user options */
- openout(); /* get an output file */
- openin(); /* and initial input file */
- header(); /* intro code */
- parse(); /* process ALL input */
- dumplits(); /* then dump literal pool */
- dumpglbs(); /* and all static memory */
- dumpextrn(); /* make all function defined extrn */
- errorsummary(); /* summarize errors */
- trailer(); /* follow-up code */
- closeout(); /* close the output */
- if (errcnt) unlink("a:$$$.sub"); /* if errors erase submit file */
- return; /* then exit to system */
- }
- /* */
- /* Process all input text */
- /* */
- /* At this level, only static declarations, */
- /* defines, includes, and function */
- /* definitions are legal... */
- parse()
- {
- while (!eof) { /* do until no more input */
- if(amatch("char",4)) {
- declglb(cchar);
- ns();
- }
- else if(amatch("int",3)) {
- declglb(cint);
- ns();
- }
- else if(match("#asm")) doasm();
- else if(match("#include")) doinclude();
- else if(match("#define")) addmac();
- else if(match("#ifndef")) doifndef();
- else if(match("#ifdef")) doifdef();
- else newfunc();
- blanks(); /* force eof if pending */
- }
- }
- /* */
- /* Dump the literal pool */
- /* */
- dumplits()
- {
- int j,k;
-
- if (litptr==0) return; /* if nothing there, exit...*/
- printlabel(litlab);
- col(); /* print literal label */
- k=0; /* init an index... */
- while (k<litptr) { /* to loop with */
- defbyte(); /* pseudo-op to define byte */
- j=10; /* max bytes per line */
- while(j--) {
- outdec(litq[k++]);
- if (j==0 || k>=litptr) {
- nl(); /* need <cr> */
- break;
- }
- outbyte(','); /* separate bytes */
- }
- }
- litptr=0;
- }
- /* */
- /* Dump all static variables */
- /* */
- dumpglbs()
- {
- int j;
- dsect("@globals");
- cptr=startglb;
- while(cptr<glbptr) {
- if (cptr[ident] != function) {
- /* do if anything but function */
- outstr(cptr);col();
- /* output name as label... */
- defstorage(); /*define storage */
- j=((cptr[offset]&255)+
- ((cptr[offset+1]&255)<<8));
- /* calc # bytes */
- outdec(j); /* need that many */
- nl();
- }
- cptr=cptr+symsiz;
- }
- }
- /* */
- /* dump extrn function */
- /* */
- dumpextrn()
- {
- char *ptr;
-
- ptr=startglb;
- while(ptr!=glbptr) {
- if (!ptr[offset]) extrn(ptr);
- ptr=ptr+symsiz;
- }
- }
- /* */
- /* Report errors for user */
- /* */
- errorsummary()
- {
- /* see if anything left hanging... */
- if (ncmp) error("missing closing bracket");
- /* open compund statment ... */
- if (!cif) error("missing closing #endif");
- nl();
- comment();
- outdec(errcnt); /* total # errors */
- outstr(" errors in compilation.");
- nl();
- }
- /* */
- /* Get options from user */
- /* */
- ask()
- {
- int k;
- kill(); /* clear input line */
- pl(" * * * small-c version 1.1 compiler * * *\n");
- /* see if user wants to interleasve the c-text */
- /* inform of comments (for clarity) */
- pl("Do you wish to c-text to appear? ");
- gets(line); /* get answer */
- if(toupper(ch())=='Y') ctext=1; /* user said yes */
- }
- /* */
- /* Get output filename */
- /* */
- openout()
- {
- kill(); /* erase line */
- output=0; /* start with none */
- pl("Output filename? "); /* ask...*/
- gets(line); /* get a filename */
- if(ch()==0)return; /* none given... */
- if ((output=fcreat(line,fout)) == ERROR) {
- output=0; /* can't open */
- error("Open failure");
- }
- kill(); /* erase line */
- }
- /* */
- /* Get (next) input file */
- /* */
- openin()
- {
- input=0; /* none to start with */
- while (!input) /* any above 1 allowed */
- {kill(); /* clear line */
- if(eof)break; /* if user said none */
- pl("Input filename? ");
- gets(line); /* get a name */
- if(ch()==0) {
- eof=1;
- break; /* none given... */
- }
- line1=0;
- if ((input=fopen(line,finp)) == ERROR) {
- input=0; /* can't open it */
- pl("Open failure");
- }
- }
- kill(); /* erase line */
- }
- /* */
- /* Open an include file */
- /* */
- doinclude()
- {
- char fname[31]; /* place to open file name */
- char fend; /* ending character for file name */
- int lenght; /* size of file name */
- while(isspace(ch())) gch(); /* skip over to name */
- fend=' ';
- if (ch()=='<') {
- fend='>';
- gch();
- }
- if (ch()=='\"') {
- fend='\"';
- gch();
- }
- lenght=0;
- while(lenght<30 && ch() && ch()!=fend) {
- fname[lenght++]=ch();
- gch();
- }
- fname[lenght]=0;
- if (!(fend == ch() || (fend ==' ' && !ch()))) {
- error("invaild file name for include");
- kill();
- return;
- }
- if (!lenght) {
- error("missing file name for include");
- kill();
- return;
- }
- line2=0;
- if (input2) {
- error("nested include not aloud");
- kill();
- return;
- }
- if ((input2=fopen(fname,finp2)) == ERROR) {
- error("Open failure on include file");
- input2=0;
- }
- kill();
- }
- /* */
- /* #ifndef */
- /* */
- doifndef()
- {
- char sname[namesize];
- int lval[2];
-
- /* check to if define as constant */
- blanks();
- if (constant(lval)) {
- cif=FALSE;
- return;
- }
-
- /* check to see if vaild sysmbol */
- if (!symname(sname)) {
- error("invaild identifier");
- kill();
- return;
- }
-
- /* check to see if symbol is define */
- if (findloc(sname) || findglb(sname))
- cif=FALSE; else cif=TRUE;
- }
- /* */
- /* #ifdef */
- /* */
- doifdef()
- {
- char sname[namesize];
- int lval[2];
-
- /* check to see if constant */
- blanks();
- if (!constant(lval)) {
- cif=FALSE;
- return;
- }
-
- /* check to see if vaild symbol */
- if (!symname(sname)) {
- error("invaild identifier");
- kill();
- }
-
- /* check to see if symbol is define */
- if (findloc(sname) || findglb(sname))
- cif=TRUE; else cif=FALSE;
- }
- /* */
- /* Close the output file */
- /* */
- closeout()
- {
- if (output) { /* if open mark end, close it */
- putc(26,fout);
- fflush(fout);
- fclose(output);
- }
- output=0; /* mark as closed */
- }
- /* */
- /* Declare a static variable */
- /* (i.e. define for use) */
- /* */
- /* makes an entry in the symbol table so subsequent */
- /* references can call symbol by name */
- declglb(typ) /* typ is cchar or cint */
- int typ;
- {
- int j;
- int count;
- char sname[namesize];
-
- while(1) {
- count=0;
- if (endst()) return;
- if(match("*")) {
- j=pointer;
- ++count;
- while(ch()=='*') {
- ++count;
- gch();
- }
- }
- else j=variable;
- if (!symname(sname)) illname();
- if(findglb(sname)) multidef(sname);
- data_parse(sname,typ,statik,j,count);
- if (match(",")==0) return; /* more? */
- }
- }
- /* */
- /* Declare local variables */
- /* (i.e. define for use) */
- /* */
- /* works just like "declglb" but modifies machine stack */
- /* and adds symbol table entry with appropriate */
- /* stack offset to find it again */
- declloc(typ) /* typ is cchar or cint */
- int typ;
- {
- int j;
- int count;
- char sname[namesize];
- while(1) {
- count=0;
- if (endst()) return;
- if (match("*")) {
- j=pointer;
- ++count;
- while(ch()=='*') {
- ++count;
- gch();
- }
- }
- else j=variable;
- if (!symname(sname)) illname();
- if (findloc(sname)) multidef(sname);
- data_parse(sname,typ,stkloc,j,count);
- if (!match(",")) return;
- }
- }
- /* */
- /* parse out data item and add to symbol */
- /* symbol table. */
- /* */
- /* written April 8, 1981 By Mike Bernson */
- /* */
- data_parse(sname,typ,class_id,ident_typ,count)
- char *sname; /* pointer to name of symbol */
- char typ; /* type of data char or int */
- char class_id; /* typ of storage static automic */
- char ident_typ; /* type of varble pointer or varble */
- int count; /* number of level of pointers */
- {
- int size; /* amount of memory needed for varble */
- int value; /* used to hold value for offset */
- char *ptr; /* pointer to free slot in symbol table */
-
- /* check to see if subscript */
- if (match("[")) {
-
- /* add 1 to inderict count */
- ++count;
-
- /* check to see null subscript */
- if (size=needsub()) {
-
- /* subscript size not null */
- if (ident_typ==pointer) {
-
- /* array of pointer *temp[size] */
- size=size+size;
- }
- else {
-
- /* array temp[size] */
- ident_typ=array;
- if (typ==cint) size=size+size;
- }
- }
- else {
-
- /* null size subscript */
- ident_typ=pointer;
- size=2;
- }
- }
- else {
- /* no subscript */
- if (ident_typ==pointer) size=2;
- else if (typ == cint) size=2; else size=1;
- }
- /* add data element to symbol table */
- switch(class_id) {
-
- /* global symbol */
- case statik :
- if (glbptr>=endglb) {
- error("global symnol table overflow");
- return 0;
- }
- ptr=glbptr;
- glbptr+=symsiz;
- value=size;
- break;
-
- /* stack local varble */
- case stkloc :
- sp=modstk(sp-size);
- value=sp;
- if (locptr>=endloc) {
- error("local symbol table overflow");
- return 0;
- }
- ptr=locptr;
- locptr+=symsiz;
- break;
-
- /* arg stack */
- case stkarg :
- value=argstk;
- argstk-=2;
- if (locptr>=endloc) {
- error("local symbol table overflow");
- return 0;
- }
- ptr=locptr;
- locptr+=symsiz;
- break;
- }
- /* file in symbol table entry */
- strcpy(ptr+name,sname);
- ptr[ident]=ident_typ;
- ptr[type]=typ;
- ptr[storage]=class_id;
- ptr[offset]=value;
- ptr[offset+1]=value>>8;
- ptr[indcnt]=count;
- return TRUE;
- }
- /* a